// 接入编辑功能
// 1 onLoad来接收id
//   判断 是否存在id 来判断出当前是 新增 - 编辑
//   有id 就是编辑
//       1 设置页面的title 修改报修信息
//       2 根据id获取 编辑的详情
//       3 设置到页面中
//   无id 就是新增
//       1 设置页面的title 填写报修信息
// 2 提交
//       1判断一下有没有id

// 导入dayjs
import dayjs from 'dayjs'
// 导入校验规则
import Schema from 'validate'

// 创建校验规则
const repairInfo = new Schema(
  {
    houseId: {
      type: String, //校验类型
      required: true, //必需的
      message: '房屋不能为空', //校验错误提示信息
    },
    repairItemId: {
      type: String, //校验类型
      required: true, //必需的
      message: '维修项目不能为空', //校验错误提示信息
    },
    mobile: {
      type: String, //校验类型
      required: true, //必需的
      match: /^1[3-9]\d{9}$/, //校验规则
      message: '手机号码不合法', //校验错误提示信息
    },
    appointment: {
      type: String, //校验类型
      required: true, //必需的
      message: '预约日期不能为空',
    },
    description: {
      type: String, //校验类型
      required: true, //必需的
      length: {
        min: 1,
        max: 200,
      }, //校验字符长度最小为1,最大为200
      message: '请输入1-200个字符', //校验错误提示信息
    },
    attachment: {
      type: Array,
      use: {
        // 自定义校验规则
        validateArray(value) {
          return !!value.length //将数字转为布尔值
        },
      },
      message: '问题附件不能为空', //校验错误提示信息
    },
  },
  { strip: false } //解决 验证对象后,数据丢失属性问题!!!
)
Page({
  data: {
    //当前日期 事件戳
    currentDate: new Date().getTime(),
    //选择报修房屋组件 显示隐藏
    houseLayerVisible: false,
    //选择维修组件 显示隐藏
    repairLayerVisible: false,
    //预约日期组件 显示隐藏
    dateLayerVisible: false,
    //选择保修房屋组件 要显示 待维修房屋列表
    houseList: [],
    //选择维修项目 要显示 维修项目
    repairItem: [],
    //问题附件  图片列表
    // 把原本的fileList改为后台需要的问题附件字段,方便后期提交
    // fileList: [
    //   { url: '/repair_pkg/static/uploads/attachment.jpg' },
    //   { url: '/repair_pkg/static/uploads/attachment.jpg' },
    // ],
    attachment: [],
    //设置日期选择器的最大时间为当前时间加上7天   dayjs()获取当前时间 +号转时间戳 add(7,'day')在当前时间加上7天
    maxDate: +dayjs().add(7, 'day'), //当前时间加7天转为时间戳
    //新增的时候我们需要根据后台所需的字段来设置字段名
    houseId: '', //选中待维修的房屋id 后台需要的
    houseInfo: '', //选中待维修的房屋名字 渲染到页面上需要的
    repairItemId: '', //选中维修项的id 后台需要的
    repairItemName: '', //选中维修项的名字 渲染到页面需要的
    mobile: '', //后台需要的手机号，双向绑定到标签中
    appointment: '', //后台需要的预约日期字段
    description: '', //后台需要的问题描述字段,双向绑定到标签中
  },
  async onLoad({ id }) {
    console.log('id  ----->  ', id)
    // 有id是编辑
    if (id) {
      // 修改标题
      wx.setNavigationBarTitle({ title: '编辑维修信息' })
      //调用获取维修详情方法
      this.getRepairDetail(id)
    } else {
      // 修改标题
      wx.setNavigationBarTitle({ title: '新增维修信息' })
    }
    // 无id是新增
    //页面加载的时候获取能保修的房屋列表
    //由于没有房子审核通过,得到的保修房屋列表是空的,我们需要手动通过接口来修改房屋状态为审核通过
    this.getHouseList()
    //调用获取维修列表数据方法
    this.getRepairList()
  },
  //封装获取维修详情
  async getRepairDetail(id) {
    //获取维修详情进行回填
    const res = await wx.http({
      url: `/repair/${id}`,
    })
    console.log('报修详情  ----->  ', res)
    const { status, ...data } = res.data
    console.log('data  ----->  ', data)
    // 由于接口返回的数据是houseInfo，原来的是houseInfo，所以我们需要全局替换方便设置回data
    // 把拿回来的数据回填给data
    this.setData({ ...data })
  },
  //封装获取我能保修的房屋列表
  async getHouseList() {
    const res = await wx.http({
      url: '/house',
    })
    // console.log('我能维修的房屋列表  ----->  ', res)
    // 把获取到的能维修的房屋列表赋值给data中的houseList
    this.setData({
      houseList: res.data,
    })
  },
  //封装获取维修列表数据
  async getRepairList() {
    const res = await wx.http({
      url: '/repairItem',
    })
    // console.log('维修列选项  ----->  ', res)
    //把获取到的维修列表设置到data中
    this.setData({
      repairItem: res.data,
    })
  },
  //选中维修房屋选项时触发的函数
  onHouseSelect(e) {
    console.log('e  ----->  ', e)
    // e.detail可以获取到id和name值,设置回data里面
    this.setData({
      houseId: e.detail.id,
      houseInfo: e.detail.name,
    })
  },
  //选中维修选项时触发的函数
  onRepairSelect(e) {
    console.log('e  ----->  ', e)
    // 把获取到的id和name设置回data中
    this.setData({
      repairItemId: e.detail.id,
      repairItemName: e.detail.name,
    })
  },
  //设置 选择保修房屋组件 显示
  openHouseLayer() {
    this.setData({ houseLayerVisible: true })
  },
  //时间选择弹窗点击确定触发的函数,有个回调参数是当前选中的值
  onDataTimeConfirm(e) {
    console.log('e  ----->  ', e)
    //时间参数里面有个detail是时间戳也就是毫秒数,我们需要转换成后台需要的格式2022-10-01
    // 时间处理一般我们不自己处理，而是使用js库 dayjs或moment来处理时间格式
    //因为如果在20号加10天超过一个月不知道应该减28还是29还是30还是31
    console.log('e.detail  ----->  ', e.detail)
    console.log('dayjs格式化日期 ', dayjs(e.detail).format('YYYY-MM-DD'))
    // 下载dayjs并在微信开发者工具重新构建并引入然后处理日期
    // 把格式化的日期设置回data中
    this.setData({
      // 将时间戳转换成2022-10-01格式设置回data中
      appointment: dayjs(e.detail).format('YYYY-MM-DD'),
      //关闭时间选中弹窗
      dateLayerVisible: false,
    })
  },
  //时间选择弹窗点击取消触发的函数
  onDataTimeCancel() {
    //点击取消关闭时间选择弹窗
    this.setData({ dateLayerVisible: false })
  },
  goList() {
    wx.reLaunch({
      url: '/repair_pkg/pages/list/index',
    })
  },
  //处理文件读取完成后的函数
  onAfterRead(e) {
    console.log('临时地址  ----->  ', e.detail.file.thumb)
    const thumb = e.detail.file.thumb //把临时地址存储起来
    //上传到服务器获取在线地址
    wx.uploadFile({
      url: wx.http.baseURL + '/upload', //由于baseURL只是设置在了wx.http上,所以这里地址我们要补全
      filePath: thumb, //要上传文件资源的路径 (本地路径)
      name: 'file', //文件对应的 key，开发者在服务端可以通过这个 key 获取文件的二进制内容 通过接口可以知道二进制文件是file
      header: {
        Authorization: `Bearer ${getApp().token}`,
      }, //由于请求头是在http请求拦截器设置的,和wx.uploadFile无关联,所以我们需要重新设置请求头
      // 上传成功的回调
      success: (res) => {
        console.log('成功上传的结果  ----->  ', res)
        // 由于返回的数据是JSON字符串，无法直接使用,所以我们需要通过JSON.parse转换为对象
        const data = JSON.parse(res.data)
        console.log('data  ----->  ', data)
        // 通过解构出data中的attachment数组,在原来的基础上追加内容,再设置回data中,这样就可以实现上传多张照片,原来的图片也不会覆盖问题
        const { attachment } = this.data
        // 由于后台要的描述附件数组中格式为{id:'',url:''}，返回的数据刚好是这种格式我们直接追加进去即可
        attachment.push(data.data)
        console.log('data.data  ----->  ', data.data)
        this.setData({
          attachment,
        })
        console.log('this.data.attachment  ----->  ', this.data.attachment)
      },
      fail: (err) => {
        console.log('上传失败的结果  ----->  ', err)
      },
    })
  },
  //图片附件点击删除触发的函数
  onDelete(e) {
    //为了用户体验,我们最好加个二次确认
    wx.showModal({
      title: '提示',
      content: '你确定删除吗?',
      // 无论是点击取消还是确定都会触发的函数
      // 直接解构confirm如果为true就是确定,false就是取消
      success: ({ confirm }) => {
        // console.log('res  ----->  ', res)
        if (confirm) {
          // console.log('  confirm----->  ', confirm)//true
          // 当用户点击了确定后把元素从数组中删除
          // console.log('e  ----->  ', e)
          const index = e.detail.index //拿到点击的哪个图片索引
          // console.log('index  ----->  ', index)
          // 把图片附件数组从data中解构出来,在原来的基础上进行删除
          const { attachment } = this.data
          attachment.splice(index, 1) //通过数组的splice(删除的索引,删几个)把元素从数组中删除
          // 把删除后的图片附件数组设置回data中
          this.setData({
            attachment,
          })
        }
      },
    })
  },
  // 控制弹窗的显示和隐藏-------------------------------------------------
  //设置 选择保修房屋组件 隐藏
  closeHouseLayer(e) {
    // 测试一下在这个函数是否能拿到所选的值
    // console.log('e  ----->  ', e) //经过测试我们发现在这个事件处理函数中拿不到选项信息,所以我们只能去查文档查找其他处理函数
    this.setData({ houseLayerVisible: false })
  },
  //设置 选择维修项目组件 显示
  openRepairLayer() {
    this.setData({ repairLayerVisible: true })
  },
  //设置 选择维修项目组件 关闭
  closeRepairLayer() {
    this.setData({
      repairLayerVisible: false,
    })
  },
  //设置 预约日期组件 显示
  openDateLayer() {
    this.setData({ dateLayerVisible: true })
  },
  //设置 预约日期组件 隐藏 (用不着了,直接注释掉)
  // closeDateLayer() {
  //   this.setData({ dateLayerVisible: false })
  // },

  //提交报修流程
  // 1.收集表单数据
  // 2.校验表单数据
  // 3.校验通过发送请求
  // 4.判断请求是否失败
  // 5.提示用户
  // 6.跳转到维修列表页面
  async onSubmit() {
    // 新增维修无须带上id
    const { id, appointment, attachment, description, houseId, mobile, repairItemId } = this.data
    //创建一个提交数据
    const data = {
      id,
      appointment,
      attachment,
      description,
      houseId,
      mobile,
      repairItemId,
    }
    // console.log('  data----->  ', data)
    // console.log('id  ----->  ', id)

    // 提交的时候判断一下:
    // 如果有id 代表编辑 带上id发请求
    // 如果没有id 代表新增 删除掉id
    if (id === undefined) {
      // 如果是undefined代表没有id，是新增我们需要删掉id再发请求
      delete data.id
    }
    // console.log('data  ----->  ', data)
    //进行表单校验
    const errors = repairInfo.validate(data)
    console.log('  errors----->  ', errors)
    if (errors.length) {
      //如果errors数组有长度的话就代表校验失败,提示用户
      wx.utils.toast(errors[0].message)
      return //并且退出函数下面发请求不再执行
    }
    // delete data.description 删掉一个参数测试请求失败是否能触发
    console.log('校验通过可以发请求了  ----->  ')
    console.log('data  ----->  ', data)
    // http插件中不管是get请求还是post请求,数据提交都是放在data中,不区分params,data
    const res = await wx.http({
      url: '/repair',
      method: 'POST',
      data, //简写的写法等于 data:data
    })
    console.log('res  ----->  ', res)

    // 判断请求如果失败,成功的状态码是10000
    if (res.code !== 10000) {
      //代表请求失败，提示用户
      wx.utils.toast(res.message)
      return //并且退出函数,下面代码不再执行
    }

    /* 如果有id代表编辑 提示编辑成功
    如果没有id代表新增 提示新增成功 */
    // 执行到这代表请求成功
    // 提示用户
    if (id) {
      wx.showToast({ title: '编辑成功' })
    } else {
      wx.showToast({ title: '新增成功' })
    }

    //跳转到维修列表页面
    // 使用延迟器延迟跳转,这样可以看到提示框
    setTimeout(() => {
      // 切记除了app.json里面的pages配置无需加/,其他的跳转路径前面一定要加上/,否则无法跳转!!!!!!!!!!
      wx.navigateTo({ url: '/repair_pkg/pages/list/index' })
    }, 1500)
  },
})
